
#region Imported Namespaces
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Windows.Forms;
#endregion

namespace UtilityTest
{
	/// <summary>
	/// This class is display the list of parameters that stored procedure expects, and allows the user to
	/// specify the value for each such parameter. It then can provide an array of those parameters back.
	/// </summary>
	public class SprocParameters : Form
	{
		#region Instance Variables
		private ListView		args;
		private ColumnHeader	argName;
		private ColumnHeader	argValue;
		private ColumnHeader	argType;
		private Panel			buttonPanel;
		private Button			cancel;
		private Container		components = null;
		private string			connectionString;
		private Button			ok;
		private SqlParameter[]	parameters;
		private string			sprocName;
		#endregion

		#region Constructor
		public SprocParameters(string connectionString, string sprocName)
		{
			InitializeComponent();

			this.connectionString = connectionString;
			this.sprocName = sprocName;
		}
		#endregion

		#region Public Properties
		public SqlParameter[] Parameters	{ get { return parameters; } }
		#endregion

		#region Overrides
		protected override void Dispose(bool disposing)
		{
			if (disposing && (components != null))
				components.Dispose();
			base.Dispose(disposing);
		}
		#endregion

		#region Event Handlers
		private void OnAfterLabelEdit(object sender, System.Windows.Forms.LabelEditEventArgs e)
		{
			// We could potential do some data validation (such as ensuring that the entered value is actually
			// of the expected type. For now, we punt...
		}

		private void OnLoad(object sender, System.EventArgs e)
		{
			SqlConnection connection = new SqlConnection(connectionString);
			try
			{
				connection.Open();
				SqlCommand command = new SqlCommand();
				command.Connection = connection;
				command.CommandType = CommandType.Text;
				command.CommandText = string.Format(@"select parameter_name, data_type from information_schema.parameters where specific_name = '{0}'", sprocName);
			
				SqlDataReader reader = command.ExecuteReader(CommandBehavior.CloseConnection);
				while (reader.Read())
				{
					ListViewItem item = new ListViewItem("?");
					item.SubItems.Add((string)reader["parameter_name"]);
					item.SubItems.Add((string)reader["data_type"]);
					args.Items.Add(item);
				}
				reader.Close();
				
				if (args.Items.Count > 0)
					args.LabelEdit = true;
				else
				{
					Visible = false;
					DialogResult = DialogResult.OK;
				}
			}
			catch (Exception ex)
			{
				MessageBox.Show(this, ex.Message, "Failed to get stored procedure arguments", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
			finally
			{
				if (connection.State != ConnectionState.Closed)
					connection.Close();
			}
		}

		private void OnOK(object sender, System.EventArgs e)
		{
			parameters = new SqlParameter[args.Items.Count];
			for (int count = args.Items.Count, i = 0; i < count; ++i)
			{
				ListViewItem item = args.Items[i];
				parameters[i] = new SqlParameter(item.SubItems[1].Text, GetSqlDbType(item.SubItems[2].Text));
				parameters[i].Value = item.Text;
			}
			DialogResult = DialogResult.OK;
		}
		#endregion

		#region Private Methods
		private SqlDbType GetSqlDbType(string typeName)
		{
			switch (typeName.ToLower())
			{
				case "int": return SqlDbType.Int;
				default: throw new Exception(string.Format("{0} is not a supported data type", typeName));
			}
		}
		#endregion

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.args = new System.Windows.Forms.ListView();
			this.argValue = new System.Windows.Forms.ColumnHeader();
			this.argName = new System.Windows.Forms.ColumnHeader();
			this.argType = new System.Windows.Forms.ColumnHeader();
			this.buttonPanel = new System.Windows.Forms.Panel();
			this.cancel = new System.Windows.Forms.Button();
			this.ok = new System.Windows.Forms.Button();
			this.buttonPanel.SuspendLayout();
			this.SuspendLayout();
			// 
			// args
			// 
			this.args.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
																				   this.argValue,
																				   this.argName,
																				   this.argType});
			this.args.Dock = System.Windows.Forms.DockStyle.Fill;
			this.args.GridLines = true;
			this.args.LabelEdit = true;
			this.args.Location = new System.Drawing.Point(0, 0);
			this.args.MultiSelect = false;
			this.args.Name = "args";
			this.args.Size = new System.Drawing.Size(292, 273);
			this.args.TabIndex = 0;
			this.args.View = System.Windows.Forms.View.Details;
			this.args.AfterLabelEdit += new System.Windows.Forms.LabelEditEventHandler(this.OnAfterLabelEdit);
			// 
			// argValue
			// 
			this.argValue.Text = "Value";
			// 
			// argName
			// 
			this.argName.Text = "Name";
			this.argName.Width = 150;
			// 
			// argType
			// 
			this.argType.Text = "Data Type";
			this.argType.Width = 100;
			// 
			// buttonPanel
			// 
			this.buttonPanel.Controls.Add(this.cancel);
			this.buttonPanel.Controls.Add(this.ok);
			this.buttonPanel.Dock = System.Windows.Forms.DockStyle.Bottom;
			this.buttonPanel.Location = new System.Drawing.Point(0, 233);
			this.buttonPanel.Name = "buttonPanel";
			this.buttonPanel.Size = new System.Drawing.Size(292, 40);
			this.buttonPanel.TabIndex = 1;
			// 
			// cancel
			// 
			this.cancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
			this.cancel.Location = new System.Drawing.Point(208, 8);
			this.cancel.Name = "cancel";
			this.cancel.TabIndex = 1;
			this.cancel.Text = "Cancel";
			// 
			// ok
			// 
			this.ok.Location = new System.Drawing.Point(120, 8);
			this.ok.Name = "ok";
			this.ok.TabIndex = 0;
			this.ok.Text = "OK";
			this.ok.Click += new System.EventHandler(this.OnOK);
			// 
			// SprocParameters
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
			this.CancelButton = this.cancel;
			this.ClientSize = new System.Drawing.Size(292, 273);
			this.Controls.Add(this.buttonPanel);
			this.Controls.Add(this.args);
			this.Name = "SprocParameters";
			this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
			this.Text = "SprocParameters";
			this.Load += new System.EventHandler(this.OnLoad);
			this.buttonPanel.ResumeLayout(false);
			this.ResumeLayout(false);

		}
		#endregion
	}
}

// --- EOF ---
